﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Configuration;
using System.Diagnostics;

namespace GestorSQL.Utility
{
    public static class TypeExtensionMethods
    {

        /// <summary>
        /// Obtiene una instancia de un objeto dado un Assembly
        /// </summary>
        /// <typeparam name="T">Tipo de dato (Normalmente una Interfaz)</typeparam>
        /// <param name="assemFilePath">Ruta física del archivo .dll</param>
        /// <param name="fullClassName">Nombre completo (con namespace) de la clase a invocar.</param>
        /// <returns>Instancia de la clase.</returns>
        public static T GetInstance<T>(this object obj, string assemFilePath, string fullClassName)
        {
            Assembly assem = Assembly.LoadFile(assemFilePath);
            Type type = assem.GetType(fullClassName);
            ConstructorInfo ctor = type.GetConstructor(new Type[] { });
            return (T)ctor.Invoke(null);
        }

        /// <summary>
        /// Obteiene el valor del parámetro del archivo de configuración 
        /// en la sección de appsetings.
        /// </summary>
        /// <returns>String del valor</returns>
        public static string GetFromAppCfg(this string appKey)
        {
            return ConfigurationManager.AppSettings[appKey];
        }

        /// <summary>
        /// Obteiene el valor del parámetro del archivo de configuración 
        /// en la sección de appsetings, y lo retorna en el tipo deseado.
        /// </summary>
        /// <typeparam name="T">Tipo al que se parseará el valor obtenido.</typeparam>
        /// <param name="appKey"></param>
        /// <returns>Valor en el tipo de dato deseado.</returns>
        public static T GetFromAppCfg<T>(this string appKey)
        {
            return (T)Convert.ChangeType(ConfigurationManager.AppSettings[appKey], typeof(T));
        }

        /// <summary>
        /// Obteiene el valor de la cadena de coneccion del archivo de configuración 
        /// en la sección de connectionStrings.
        /// </summary>
        /// <returns>Cadena de conección.</returns>
        public static string GetFromConnStrings(this string connectionStringName)
        {
            return ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
        }

        /// <summary>
        /// Obtiene el namespace y nombre del método desde el que se hace el llamado.
        /// </summary>
        /// <param name="me">this</param>
        /// <returns>namespace:metodo</returns>
        public static string GetSource(this object me)
        {
            string _namespace = me.GetType().FullName;

            StackTrace stackTrace = new StackTrace();
            StackFrame stackFrame = stackTrace.GetFrame(1);
            MethodBase methodBase = stackFrame.GetMethod();

            string _methodName = methodBase.Name;

            return string.Format("{0}:{1}", _namespace, _methodName);
        }

        public static string CombinePath(this string path, string fileName)
        {
            return System.IO.Path.Combine(path, fileName);
        }

        public static string CombinePathFromAppCfg(this string appKeyPath, string appKeyfileName)
        {
            return System.IO.Path.Combine(appKeyPath.GetFromAppCfg(), appKeyfileName.GetFromAppCfg());
        }
    }
}
